package top.codedance.iotp.common.handler;

import top.codedance.iotp.common.constent.Command;
import top.codedance.iotp.common.entity.CommonEntity;
import cd.io.netty.channel.ChannelHandlerContext;
import cd.io.netty.channel.SimpleChannelInboundHandler;
import cd.io.netty.handler.timeout.IdleStateEvent;
import org.apache.log4j.Logger;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

abstract public class AbsractIdleHandler extends SimpleChannelInboundHandler<CommonEntity> {
    private static ExecutorService pool = Executors.newCachedThreadPool();
    private static Logger logger;

    public AbsractIdleHandler(Logger logger){
        this.logger = logger;
    }

    @Override
    protected void messageReceived(ChannelHandlerContext channelHandlerContext, CommonEntity commonEntity) throws Exception {
        if(commonEntity.getCommand() == Command.HEARTEAT_PONG){
            logger.debug("Get pong msg from " + channelHandlerContext.channel().remoteAddress());
        } else if(commonEntity.getCommand() == Command.HEARTEAT_PING){
            sendPongMsg(channelHandlerContext);
            logger.debug("Get ping msg from " + channelHandlerContext.channel().remoteAddress());
        }else{
            channelHandlerContext.fireChannelRead(commonEntity); //向后传递
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            switch (e.state()) {
                case READER_IDLE:
                    handleReaderIdle(ctx);
                    break;
                case WRITER_IDLE:
                    handleWriterIdle(ctx);
                    break;
                case ALL_IDLE:
                    handleAllIdle(ctx);
                    break;
                default:
                    break;
            }
        }
    }

    protected void sendPingMsg(final ChannelHandlerContext channelHandlerContext) {
        pool.submit(() -> {
            CommonEntity commonEntity2 = new CommonEntity();
            commonEntity2.setCommand(Command.HEARTEAT_PING);
            channelHandlerContext.write(commonEntity2.build());
            channelHandlerContext.flush();
        });
    }

    protected void sendPongMsg(final ChannelHandlerContext channelHandlerContext) {
        pool.submit(() -> {
            CommonEntity commonEntity2 = new CommonEntity();
            commonEntity2.setCommand(Command.HEARTEAT_PONG);
            channelHandlerContext.write(commonEntity2.build());
            channelHandlerContext.flush();
        });
    }

    protected void handleReaderIdle(ChannelHandlerContext ctx) {}

    protected void handleWriterIdle(ChannelHandlerContext ctx) {}

    protected void handleAllIdle(ChannelHandlerContext ctx) {}
}
